﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;

namespace BesAsm.Framework.ArcGisUtilities
{
  /// <summary>
  /// Provides commonly performed functions and services related to feature layers
  /// </summary>
  public abstract class FeatureLayerDecorator : IFeatureLayer, IFeatureLayerSelectionEvents_Event, IFeatureLayerDefinition, IFeatureSelection, IGeoFeatureLayer, IDataset
  {
    protected IFeatureLayer _layer;
    private IFeatureLayerSelectionEvents_Event _featureLayerSelectionEvents;

    public FeatureLayerDecorator()
    {
      throw new NotSupportedException("Not used required by compiler");
    }

    public static implicit operator FeatureLayerClass(FeatureLayerDecorator layer)
    {
      return layer._layer as FeatureLayerClass;
    }

    protected FeatureLayerDecorator(IFeatureLayer featureLayer)
    {
      if (!(featureLayer is FeatureLayer) && !(featureLayer is FeatureLayerDecorator))
        throw new ArgumentException("Argument featureLayer must be an ESRI.ArcGIS.Carto.FeatureLayer CoClass");

      _layer = featureLayer;

      _featureLayerSelectionEvents = (IFeatureLayerSelectionEvents_Event)_layer;
      _featureLayerSelectionEvents.FeatureLayerSelectionChanged +=
        new IFeatureLayerSelectionEvents_FeatureLayerSelectionChangedEventHandler
          (FeatureLayerSelectionChangedEvent);
    }

    #region IFeatureLayer Members

    /// <summary>
    /// Implemented by this EmgaatsLayer object's internal FeatureLayer
    /// </summary>
    public ESRI.ArcGIS.Geometry.IEnvelope AreaOfInterest
    {
      get { return _layer.AreaOfInterest; }
    }

    /// <summary>
    /// Implemented by this EmgaatsLayer object's internal FeatureLayer
    /// </summary>
    public bool Cached
    {
      get
      {
        return _layer.Cached;
      }
      set
      {
        _layer.Cached = value;
      }
    }

    /// <summary>
    /// Implemented by this EmgaatsLayer object's internal FeatureLayer
    /// </summary>
    public string DataSourceType
    {
      get
      {
        return _layer.DataSourceType;
      }
      set
      {
        _layer.DataSourceType = value;
      }
    }

    /// <summary>
    /// Implemented by this EmgaatsLayer object's internal FeatureLayer
    /// </summary>
    public string DisplayField
    {
      get
      {
        return _layer.DisplayField;
      }
      set
      {
        _layer.DisplayField = value;
      }
    }

    /// <summary>
    /// Implemented by this EmgaatsLayer object's internal FeatureLayer
    /// </summary>
    public void Draw(ESRI.ArcGIS.esriSystem.esriDrawPhase DrawPhase, ESRI.ArcGIS.Display.IDisplay Display, ESRI.ArcGIS.esriSystem.ITrackCancel TrackCancel)
    {
      _layer.Draw(DrawPhase, Display, TrackCancel);
    }

    /// <summary>
    /// Implemented by this EmgaatsLayer object's internal FeatureLayer
    /// </summary>
    public ESRI.ArcGIS.Geodatabase.IFeatureClass FeatureClass
    {
      get
      {
        return _layer.FeatureClass;
      }
      set
      {
        _layer.FeatureClass = value;
      }
    }

    /// <summary>
    /// Implemented by this EmgaatsLayer object's internal FeatureLayer
    /// </summary>
    public double MaximumScale
    {
      get
      {
        return _layer.MaximumScale;
      }
      set
      {
        _layer.MaximumScale = value;
      }
    }

    /// <summary>
    /// Implemented by this EmgaatsLayer object's internal FeatureLayer
    /// </summary>
    public double MinimumScale
    {
      get
      {
        return _layer.MinimumScale;
      }
      set
      {
        _layer.MinimumScale = value;
      }
    }

    /// <summary>
    /// Implemented by this EmgaatsLayer object's internal FeatureLayer
    /// </summary>
    public string Name
    {
      get
      {
        return _layer.Name;
      }
      set
      {
        _layer.Name = value;
      }
    }

    /// <summary>
    /// Implemented by this EmgaatsLayer object's internal FeatureLayer
    /// </summary>
    public bool ScaleSymbols
    {
      get
      {
        return _layer.ScaleSymbols;
      }
      set
      {
        _layer.ScaleSymbols = value;
      }
    }

    /// <summary>
    /// Implemented by this EmgaatsLayer object's internal FeatureLayer
    /// </summary>
    public ESRI.ArcGIS.Geodatabase.IFeatureCursor Search(ESRI.ArcGIS.Geodatabase.IQueryFilter queryFilter, bool recycling)
    {
      return _layer.Search(queryFilter, recycling);
    }

    /// <summary>
    /// Implemented by this EmgaatsLayer object's internal FeatureLayer
    /// </summary>
    public bool Selectable
    {
      get
      {
        return _layer.Selectable;
      }
      set
      {
        _layer.Selectable = value;
      }
    }

    /// <summary>
    /// Implemented by this EmgaatsLayer object's internal FeatureLayer
    /// </summary>
    public bool ShowTips
    {
      get
      {
        return _layer.ShowTips;
      }
      set
      {
        _layer.ShowTips = value;
      }
    }

    /// <summary>
    /// Implemented by this EmgaatsLayer object's internal FeatureLayer
    /// </summary>
    public ESRI.ArcGIS.Geometry.ISpatialReference SpatialReference
    {
      set { _layer.SpatialReference = value; }
    }

    /// <summary>
    /// Implemented by this EmgaatsLayer object's internal FeatureLayer
    /// </summary>
    public int SupportedDrawPhases
    {
      get { return _layer.SupportedDrawPhases; }
    }

    /// <summary>
    /// Implemented by this EmgaatsLayer object's internal FeatureLayer
    /// </summary>
    public bool Valid
    {
      get { return _layer.Valid; }
    }

    /// <summary>
    /// Implemented by this EmgaatsLayer object's internal FeatureLayer
    /// </summary>
    public bool Visible
    {
      get
      {
        return _layer.Visible;
      }
      set
      {
        _layer.Visible = value;
      }
    }

    /// <summary>
    /// Implemented by this EmgaatsLayer object's internal FeatureLayer
    /// </summary>
    public string get_TipText(double x, double y, double Tolerance)
    {
      return _layer.get_TipText(x, y, Tolerance);
    }

    #endregion

    #region IFeatureLayerSelectionEvents_Event Members

    public event IFeatureLayerSelectionEvents_FeatureLayerSelectionChangedEventHandler FeatureLayerSelectionChanged;

    /// <summary>
    /// Raises the FeatureLayerSelectionChanged whenever the inner IFeatureLayer's 
    /// FeatureLayerSelectionChangedEvent is raised
    /// </summary>
    private void FeatureLayerSelectionChangedEvent()
    {
      if (FeatureLayerSelectionChanged != null)
      {
        FeatureLayerSelectionChanged();
      }
    }


    #endregion

    #region IFeatureLayerDefinition Members

    /// <summary>
    /// Implemented by this EmgaatsLayer object's internal FeatureLayer
    /// </summary>
    public IFeatureLayer CreateSelectionLayer(string LayerName, bool useCurrentSelection, string joinTableNames, string Expression)
    {
      return (_layer as IFeatureLayerDefinition).CreateSelectionLayer(LayerName, useCurrentSelection, joinTableNames, Expression);
    }

    /// <summary>
    /// Implemented by this EmgaatsLayer object's internal FeatureLayer
    /// </summary>
    public string DefinitionExpression
    {
      get
      {
        return (_layer as IFeatureLayerDefinition).DefinitionExpression;
      }
      set
      {
        (_layer as IFeatureLayerDefinition).DefinitionExpression = value;
      }
    }

    /// <summary>
    /// Implemented by this EmgaatsLayer object's internal FeatureLayer
    /// </summary>
    public ESRI.ArcGIS.Geodatabase.ISelectionSet DefinitionSelectionSet
    {
      get { return (_layer as IFeatureLayerDefinition).DefinitionSelectionSet; }
    }

    /// <summary>
    /// Implemented by this EmgaatsLayer object's internal FeatureLayer
    /// </summary>
    public ESRI.ArcGIS.Geodatabase.IRelationshipClass RelationshipClass
    {
      get
      {
        return (_layer as IFeatureLayerDefinition).RelationshipClass;
      }
      set
      {
        (_layer as IFeatureLayerDefinition).RelationshipClass = value;
      }
    }

    #endregion

    #region IFeatureSelection Members

    public void Add(ESRI.ArcGIS.Geodatabase.IFeature Feature)
    {
      (_layer as IFeatureSelection).Add(Feature);
    }

    public double BufferDistance
    {
      get
      {
        return (_layer as IFeatureSelection).BufferDistance;
      }
      set
      {
        (_layer as IFeatureSelection).BufferDistance = value;
      }
    }

    public void Clear()
    {
      (_layer as IFeatureSelection).Clear();
    }

    public esriSelectionResultEnum CombinationMethod
    {
      get
      {
        return (_layer as IFeatureSelection).CombinationMethod;
      }
      set
      {
        (_layer as IFeatureSelection).CombinationMethod = value;
      }
    }

    public void SelectFeatures(ESRI.ArcGIS.Geodatabase.IQueryFilter Filter, esriSelectionResultEnum Method, bool justOne)
    {
      (_layer as IFeatureSelection).SelectFeatures(Filter, Method, justOne);
    }

    public void SelectionChanged()
    {
      (_layer as IFeatureSelection).SelectionChanged();
    }

    public ESRI.ArcGIS.Display.IColor SelectionColor
    {
      get
      {
        return (_layer as IFeatureSelection).SelectionColor;
      }
      set
      {
        (_layer as IFeatureSelection).SelectionColor = value;
      }
    }

    public ESRI.ArcGIS.Geodatabase.ISelectionSet SelectionSet
    {
      get
      {
        return (_layer as IFeatureSelection).SelectionSet;
      }
      set
      {
        (_layer as IFeatureSelection).SelectionSet = value;
      }
    }

    public ESRI.ArcGIS.Display.ISymbol SelectionSymbol
    {
      get
      {
        return (_layer as IFeatureSelection).SelectionSymbol;
      }
      set
      {
        (_layer as IFeatureSelection).SelectionSymbol = value;
      }
    }

    public bool SetSelectionSymbol
    {
      get
      {
        return (_layer as IFeatureSelection).SetSelectionSymbol;
      }
      set
      {
        (_layer as IFeatureSelection).SetSelectionSymbol = value;
      }
    }

    #endregion

    #region IGeoFeatureLayer Members

    public IAnnotateLayerPropertiesCollection AnnotationProperties
    {
      get
      {
        return (_layer as IGeoFeatureLayer).AnnotationProperties;
      }
      set
      {
        (_layer as IGeoFeatureLayer).AnnotationProperties = value;
      }
    }

    public ESRI.ArcGIS.esriSystem.UID AnnotationPropertiesID
    {
      get
      {
        return (_layer as IGeoFeatureLayer).AnnotationPropertiesID;
      }
      set
      {
        (_layer as IGeoFeatureLayer).AnnotationPropertiesID = value;
      }
    }

    public int CurrentMapLevel
    {
      set { (_layer as IGeoFeatureLayer).CurrentMapLevel = value; }
    }

    public bool DisplayAnnotation
    {
      get
      {
        return (_layer as IGeoFeatureLayer).DisplayAnnotation;
      }
      set
      {
        (_layer as IGeoFeatureLayer).DisplayAnnotation = value;
      }
    }

    public ESRI.ArcGIS.Geodatabase.IFeatureClass DisplayFeatureClass
    {
      get { return (_layer as IGeoFeatureLayer).DisplayFeatureClass; }
    }

    public IFeatureIDSet ExclusionSet
    {
      get
      {
        return (_layer as IGeoFeatureLayer).ExclusionSet;
      }
      set
      {
        (_layer as IGeoFeatureLayer).ExclusionSet = value;
      }
    }

    public IFeatureRenderer Renderer
    {
      get
      {
        return (_layer as IGeoFeatureLayer).Renderer;
      }
      set
      {
        (_layer as IGeoFeatureLayer).Renderer = value;
      }
    }

    public ESRI.ArcGIS.esriSystem.UID RendererPropertyPageClassID
    {
      get
      {
        return (_layer as IGeoFeatureLayer).RendererPropertyPageClassID;
      }
      set
      {
        (_layer as IGeoFeatureLayer).RendererPropertyPageClassID = value;
      }
    }

    public ESRI.ArcGIS.Geodatabase.IFeatureCursor SearchDisplayFeatures(ESRI.ArcGIS.Geodatabase.IQueryFilter queryFilter, bool recycling)
    {
      return (_layer as IGeoFeatureLayer).SearchDisplayFeatures(queryFilter, recycling);
    }

    #endregion

    #region IDataset Members

    public string BrowseName
    {
      get
      {
        return (_layer as IDataset).BrowseName;
      }
      set
      {
        (_layer as IDataset).BrowseName = value;
      }
    }

    public bool CanCopy()
    {
      return (_layer as IDataset).CanCopy();
    }

    public bool CanDelete()
    {
      return (_layer as IDataset).CanDelete();
    }

    public bool CanRename()
    {
      return (_layer as IDataset).CanRename();
    }

    public string Category
    {
      get { return (_layer as IDataset).Category; }
    }

    public IDataset Copy(string copyName, IWorkspace copyWorkspace)
    {
      return (_layer as IDataset).Copy(copyName, copyWorkspace);
    }

    public void Delete()
    {
      (_layer as IDataset).Delete();
    }

    public ESRI.ArcGIS.esriSystem.IName FullName
    {
      get { return (_layer as IDataset).FullName; }
    }

    public ESRI.ArcGIS.esriSystem.IPropertySet PropertySet
    {
      get { return (_layer as IDataset).PropertySet; }
    }

    public void Rename(string Name)
    {
      (_layer as IDataset).Rename(Name);
    }

    public IEnumDataset Subsets
    {
      get { return (_layer as IDataset).Subsets; }
    }

    public esriDatasetType Type
    {
      get { return (_layer as IDataset).Type; }
    }

    public IWorkspace Workspace
    {
      get { return (_layer as IDataset).Workspace; }
    }

    #endregion

  }
}
